﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;
using System.IO;
using System.Reflection;

namespace TV_Organizer
{
    class ConnectorsManager
    {
        [ImportMany(AllowRecomposition = true, RequiredCreationPolicy = CreationPolicy.Shared)]
        private IEnumerable<Lazy<ITVShowsConnector<TVShow>, ITVShowsConnectorMetadata>> _tvShowsConnectors { get; set; }
        [ImportMany(AllowRecomposition = true)]
        private IEnumerable<Lazy<ITVSubtitlesConnector, ITVSubtitlesConnectorMetadata>> _tvSubtitlesConnectors { get; set; }
        
        private AggregateCatalog _catalog;
        private CompositionContainer _container;

        #region Singleton pattern
        private ConnectorsManager()
        {
            this.Initialize();
        }

        private static ConnectorsManager _instance = new ConnectorsManager();
        public static ConnectorsManager Instance
        {
            get { return _instance; }
        }
        #endregion

        private void Initialize()
        {
            _catalog = new AggregateCatalog();
            _catalog.Catalogs.Add(new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)));
            _catalog.Catalogs.Add(new AssemblyCatalog((Assembly.GetExecutingAssembly())));

            _container = new CompositionContainer(_catalog);

            try
            {
                _container.ComposeParts(this);
            }
            catch (CompositionException compositionException)
            {
                Console.WriteLine(compositionException.ToString());
            }

            this.TVShowsServices = new List<string>(_tvShowsConnectors.Select(entry => entry.Metadata.ShowsServiceName));
            this.TVSubtitlesServices = new List<string>(_tvSubtitlesConnectors.Select(entry => entry.Metadata.SubtitlesServiceName));
        }

        public ITVShowsConnector<TVShow> GetTVShowsConnector(string serviceName)
        {
            lock (_tvShowsConnectors)
            {
                return _tvShowsConnectors.FirstOrDefault(entry => entry.Metadata.ShowsServiceName == serviceName).Value;
            }
        }

        public ITVSubtitlesConnector GetTVSubtitlesConnector(string serviceName)
        {
            return _tvSubtitlesConnectors.FirstOrDefault(entry => entry.Metadata.SubtitlesServiceName == serviceName).Value;
        }

        public List<string> TVShowsServices { get; private set; }
        public List<string> TVSubtitlesServices { get; private set; }
    }
}
